{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "支持向量机SVM(Support Vector Machines)：\n",
    "+ SVM寻找区分两类的超平面（hyper plane), 使边际(margin)最大\n",
    "\n",
    "\n",
    "SVM的优点\n",
    "+ 训练好的模型的算法复杂度是由支持向量的个数决定的，<br>\n",
    "而不是由数据的维度决定的。所以SVM不太容易产overfitting \n",
    "+ SVM训练出来的模型完全依赖于支持向量(Support  <br>\n",
    "Vectors), 即使训练集里面所有非支持向量的点都被去 <br>\n",
    "除，重复训练过程，结果仍然会得到完全一样的模型。\n",
    "+ 一个SVM如果训练得出的支持向量个数比较小，SVM <br>\n",
    "训练出的模型比较容易被泛化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import svm\n",
    "from sklearn.metrics import classification_report"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建40个点\n",
    "x_data = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]\n",
    "y_data = [0]*20 +[1]*20\n",
    "\n",
    "plt.scatter(x_data[:,0],x_data[:,1],c=y_data)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#fit the model kernel='rbf'#非线性\n",
    "model = svm.SVC(kernel='linear')\n",
    "model.fit(x_data, y_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.coef_\n",
    "model.intercept_\n",
    "print(model.support_vectors_)# 打印支持向量\n",
    "print(model.support_) # 第2和第0个点是支持向量\n",
    "print(model.n_support_)# 有几个支持向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.intercept_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 获取分离平面 \n",
    "\n",
    "plt.scatter(x_data[:,0],x_data[:,1],c=y_data)\n",
    "x_test = np.array([[-5],[5]])\n",
    "d = -model.intercept_/model.coef_[0][1]\n",
    "k = -model.coef_[0][0]/model.coef_[0][1]\n",
    "y_test = d + k*x_test\n",
    "plt.plot(x_test, y_test, 'k')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.support_vectors_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 画出通过支持向量的分界线\n",
    "b1 = model.support_vectors_[0]\n",
    "y_down = k*x_test + (b1[1] - k*b1[0])\n",
    "b2 = model.support_vectors_[-1]\n",
    "y_up = k*x_test + (b2[1] - k*b2[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.scatter(x_data[:,0],x_data[:,1],c=y_data)\n",
    "x_test = np.array([[-5],[5]])\n",
    "d = -model.intercept_/model.coef_[0][1]\n",
    "k = -model.coef_[0][0]/model.coef_[0][1]\n",
    "y_test = d + k*x_test\n",
    "plt.plot(x_test, y_test, 'k')\n",
    "plt.plot(x_test, y_down, 'r--')\n",
    "plt.plot(x_test, y_up, 'b--')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "SVM-低维映射高维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from sklearn import datasets\n",
    "from mpl_toolkits.mplot3d import Axes3D  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_data, y_data = datasets.make_circles(n_samples=500, factor=.3, noise=.10)\n",
    "plt.scatter(x_data[:,0], x_data[:,1], c=y_data)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z_data =  x_data[:,0]**2 + x_data[:,1]**2\n",
    "ax = plt.figure().add_subplot(111, projection = '3d') \n",
    "ax.scatter(x_data[:,0], x_data[:,1], z_data, c = y_data, s = 10) #点为红色三角形  \n",
    "  \n",
    "#显示图像  \n",
    "plt.show()  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# SVM-人脸识别import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.datasets import fetch_lfw_people\n",
    "from sklearn.model_selection  import GridSearchCV\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.decomposition import PCA\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4) # 载入数据\n",
    "plt.imshow(lfw_people.images[6],cmap='gray')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train, x_test, y_train, y_test = train_test_split(lfw_people.data, lfw_people.target)\n",
    "model = SVC(kernel='rbf', class_weight='balanced')\n",
    "model.fit(x_train, y_train)\n",
    "predictions = model.predict(x_test)\n",
    "print(classification_report(y_test, predictions, target_names=lfw_people.target_names))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# PCA降维\n",
    "n_components = 100 # 100个维度\n",
    "\n",
    "pca = PCA(n_components=n_components, whiten=True).fit(lfw_people.data)\n",
    "\n",
    "x_train_pca = pca.transform(x_train)\n",
    "x_test_pca = pca.transform(x_test)\n",
    "model = SVC(kernel='rbf', class_weight='balanced')\n",
    "model.fit(x_train_pca, y_train)\n",
    "predictions = model.predict(x_test_pca)\n",
    "print(classification_report(y_test, predictions, target_names=target_names))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 调参\n",
    "param_grid = {'C': [0.1, 1, 5, 10, 100],\n",
    "              'gamma': [0.0005, 0.001, 0.005, 0.01], }\n",
    "model = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)\n",
    "model.fit(x_train_pca, y_train)\n",
    "print(model.best_estimator_)\n",
    "predictions = model.predict(x_test_pca)\n",
    "print(classification_report(y_test, predictions, target_names=target_names))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "param_grid = {'C': [0.1, 0.6, 1, 2, 3],\n",
    "              'gamma': [0.003, 0.004, 0.005, 0.006, 0.007], }\n",
    "model = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)\n",
    "model.fit(x_train_pca, y_train)\n",
    "print(model.best_estimator_)\n",
    "predictions = model.predict(x_test_pca)\n",
    "print(classification_report(y_test, predictions, target_names=target_names))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  画图"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}